# coding=utf-8
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets, status
from MSB_ERP.utils.base_views import MultipleDestoryMixin # 批量删除
from erp_system.models import PermissionsModel,RolesModel,MenuModel
from MSB_ERP.apps.erp_system.serializer.role_serializer import RolesPartialSerializer,RoleSetPermissionSerializer,BaseRolesSerializer
from rest_framework.decorators import action
from rest_framework.response import Response

# 角色数据库中有一个固定的角色：admin，这个角色代表所有权限
class RolesView(viewsets.ModelViewSet,MultipleDestoryMixin):
    '''
        create:
        角色--新增

        角色新增，status：201（成功），return:新角色信息

        destroy:
        角色--删除单个角色

        角色删除，status：204（成功），return:None

        multiple_delete:
        角色--批量删除

        角色批量删除，status：204（成功），return:None

        update:
        角色--修改，仅仅是修改角色名称

        角色修改，status：200（成功），return:修改增角色信息

        partial_update:
        角色--局部修改（角色批量授权），只能针对某一个角色一次性授权，之前的授权会被覆盖

        角色局部修改，status：200（成功），return:修改增角色信息

        list:
        角色--获得所有的角色

        角色列表信息，status：200（成功），return:角色信息列表

        set_permission_to_role:
        给单个角色，单一授权，一次只能授予该角色一个permission，也可以取消一个permission

        角色列表信息，status：200（成功），return:修改后的角色信息
    '''

    queryset = RolesModel.objects.all()

    # 指定序列化的类
    # 重写序列化的类（根据不同的情况来进行赋值操作）
    def get_serializer_class(self):
        # 判断是否是上面的批量授权
        if self.action == 'partial_update':
            return RolesPartialSerializer
        elif self.action == 'set_permission_to_role':
            return RoleSetPermissionSerializer
        # 最后一种情况就是普通的序列化类
        else:
            return BaseRolesSerializer

    @action(methods=['post'],detail=False)
    def set_permission_to_role(self,request,*args,**kwargs):
        #给单个角色，单一授权，也可以取消一个permission
        ser = RolesPartialSerializer(data=request.data)
        if ser.is_valid(): # 参数验证通过了
            # 查询当前的角色（role_id是序列化里面定义的那个）
            ser = RoleSetPermissionSerializer(data=request.data)
            if ser.is_valid():
                # 查询当前的角色
                role = RolesModel.objects.get(id=ser.validated_data.get('role_id'))
                # 查询当前的权限
                permission = PermissionsModel.objects.get(id=ser.validated_data.get('permission_id'))
                if ser.validated_data.get('is_create'):
                    # 判断该权限所对应的父菜单权限是否被赋予
                    # 得到该权限对应的接口菜单的父菜单
                    # parent这个就是默认拿ID的，也可以parent__id两种写法都可以
                    parent_ids = MenuModel.objects.filter(id=permission.menu.id).values_list('parent',flat=True).all()
                    if parent_ids:
                        parent_permission = PermissionsModel.objects.get(menu_id=parent_ids[0])
                        role.permissions.add(parent_permission) # 把父菜单权限也加进去
                    role.permissions.add(permission) # 把当前的权限授予当前角色
                else: # 取消授权
                    role.permissions.remove(permission)

                result = BaseRolesSerializer(instance=role)
                return Response(data=result.data)

    # 重写父类的删除函数destroy，因为admin角色不能删除
    def destroy(self, request, *args, **kwargs):
        # 判断要删的用户是不是admin用户
        if self.get_object().name == 'admin':
            return Response(data={'detail':'admin角色不可删除'},status=status.HTTP_400_BAD_REQUEST)
        return super().destroy(request,*args,**kwargs)

    del_ids = openapi.Schema(type=openapi.TYPE_OBJECT, required=['ids'], properties={
        # 参数名：接一个类型（类型一个是openapi.Schema开头的）
        # 因为他是整数，所以要openapi.TYPE_INTEGER整数类型
        'ids': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_INTEGER),
                              description='选择那些需要删除（主键）的列表')
    })
    # 这个是特别的接口文档，methods表示请求的方法，request_body表示指定传参
    @swagger_auto_schema(method='delete', request_body=del_ids, operation_description='批量删除')  # 装饰器一定要写在action的上面
    @action(methods=['delete'], detail=False)
    def multiple_delete(self,request,*args,**kwargs):
        # 得到所有要删除的ID
        delete_ids = request.data.get('ids')
        try:
            admin = RolesModel.objects.get(name='admin')
            # 判断传过来的数据是不是list类型
            if isinstance(delete_ids,list):
                if admin.id in delete_ids:
                    return Response(data={'detail': 'admin角色不可删除'}, status=status.HTTP_400_BAD_REQUEST)
        except RolesModel.DoesNotExist as ex:
            pass
        # 最后进行批量删除
        return super().multiple_delete(request,*args,**kwargs)





